﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;
using System.Threading;

namespace DotNET4Study.同步学习
{
    class ConcurentDictionaryStudy
    {
        public static object ObjectLocked = new object();
        public static void Execute()
        {
            ConcurrentDictionary<int, string> concurentDictionary = new ConcurrentDictionary<int, string>();
            List<Thread> threadList = new List<Thread>();
            ManualResetEvent manualResetEvent = new ManualResetEvent(false);
            int timedCalled = 0;

            Lazy<int> myLazy = new Lazy<int>(() => { timedCalled++; return 1; });

            for (int i = 0; i < 50; i++)
            {
                threadList.Add(new Thread(() =>
                {
                    manualResetEvent.WaitOne();

                    ////1.缺省情形下，ConcurrentDictionary无法保证线程的同步
                    //concurentDictionary.GetOrAdd(1, p =>
                    //{
                    //    timedCalled++;
                    //    //Interlocked.Increment(ref timedCalled);
                    //    return "";
                    //});
                    
                    ////2.如果要同步，还需要自己锁定代码
                    //lock (ObjectLocked)
                    //{
                    //    concurentDictionary.GetOrAdd(1, p =>
                    //    {
                    //        timedCalled++;
                    //        //Interlocked.Increment(ref timedCalled);
                    //        return "";
                    //    });
                    //}

                    //3.如果同步，或者使用Lazy类进行处理
                    concurentDictionary.GetOrAdd(1, p =>
                    {
                        return myLazy.Value.ToString();
                    });
                }));

                threadList.Last().Start();
            }

            manualResetEvent.Set();

            Thread.Sleep(1000);
            Console.WriteLine(timedCalled);
        }
    }
}
